﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace System.Peppers.Win32
{
    /// <summary>
    /// Allocates and marshals a byte[] to unmanaged space
    /// </summary>
    public sealed class UnmanagedByteArray : UnmanagedObject
    {
        private static byte[] LoadStream(Stream stream)
        {
            byte[] bytes = new byte[(int)stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            return bytes;
        }

        /// <summary>
        /// Constructor for a byte[]
        /// </summary>
        /// <param name="bytes">byte[] to marshal</param>
        public UnmanagedByteArray(byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0)
            {
                return;
            }

            Handle = Marshal.AllocHGlobal(Marshal.SizeOf(bytes[0]) * bytes.Length);

            Marshal.Copy(bytes, 0, Handle, bytes.Length);
        }

        /// <summary>
        /// Constructor for a Stream, will load the entire stream
        /// </summary>
        /// <param name="stream">Stream to marshal</param>
        public UnmanagedByteArray(Stream stream)
            : this(LoadStream(stream))
        { }

        /// <summary>
        /// Calls Marshal.FreeHGlobal on the handle
        /// </summary>
        public override void Dispose()
        {
            base.Dispose();

            if (Handle != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(Handle);
                Handle = IntPtr.Zero;
            }
        }
    }
}
